package channel;

import java.io.InputStream;
import java.util.Properties;

import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.search.*;

import stream.Stream;



public class ChannelMail implements Channel {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	
	static public final int TYPE = EMAIL;
	
	public static void main(String[] args) {
		ChannelMail channelMail = new ChannelMail();
/*		channelMail.setFrom("Bolsheviki@126.com");
		channelMail.setKey("Re");
		int u = channelMail.THIS();
		System.out.println(u);
*/		
		channelMail.setSubject("Hello");
		channelMail.setBody("Hi");
		channelMail.setTo("Bolsheviki@yeah.net");
		channelMail.THAT();
	}
	
	
	private String subject;	//that
	private String from;	//this
	private String to;		//that
	private String body;	//that
	private String key;		//this
	
	
	public ChannelMail() {
		key = "";
	}
	
	public ChannelMail(String subject, String object, 
					   String from, String to, String key) {
		this.subject = subject;
		this.body = object;
		this.from = from;
		this.to = to;
		this.key = key;
	}
	
	
	@SuppressWarnings("finally")
	@Override
	public int THIS() {
		
		int newMailNum = 0;
		try {
			newMailNum = recv();
			
		} catch (MessagingException e) {
			newMailNum = 0;
			e.printStackTrace();
			
		} finally {
			return newMailNum;
		}
	}

	@Override
	public void THAT() {
		// TODO Auto-generated method stub
		try {
			send();
		} catch (MessagingException e) {
			e.printStackTrace();
		}
	}
	
	/** receive the message, return whether new mail exists */
	private int recv() throws MessagingException {
		int newMailNum = 0;
		
		// set properties
		Properties props = new Properties();
		props.setProperty("mail.imap.port", "143");
		
		Session session = Session.getInstance(props);
		
		// connect store
		Store store = session.getStore("imap");
		store.connect("imap.yeah.net", TRIGGER_ADDRESS, TRIGGER_PASSWORD);
		
		// get the folder
		Folder folder = store.getFolder("inbox");
		folder.open(Folder.READ_WRITE);
		
		SearchTerm[] searchTerms = {
			new FromStringTerm(from),
			new SubjectTerm(key),
			new FlagTerm(new Flags(Flags.Flag.SEEN), false)
		};
		
		// search
		SearchTerm searchTerm = new AndTerm(searchTerms);
		
		// get messages from folder
		Message[] messages = folder.search(searchTerm);
		newMailNum = messages.length;
		
		for (Message message : messages) {
			message.setFlag(Flags.Flag.SEEN, true);
//			message.saveChanges();
		}
		
		folder.close(true);
		store.close();
		
		// return whether new mail exists
		return newMailNum;
	}
	
	/** send email */
	private void send() throws MessagingException {
		// set Properties
		Properties props = new Properties();
		props.setProperty("mail.smtp.auth", "true");
		// port use default
		
		// access to session
		Session session = Session.
				getInstance(props, new Authenticator() {
			
			protected PasswordAuthentication 
								getPasswordAuthentication() {
				return new PasswordAuthentication(TRIGGER_ADDRESS, TRIGGER_PASSWORD);
			}
		});

		// packet the message and send it out
        MimeMessage message = packetMessage(session);
		
		// connect Transport
		Transport transport = session.getTransport("smtp");
		transport.connect("smtp.yeah.net", TRIGGER_ADDRESS, TRIGGER_PASSWORD);
		
		transport.sendMessage(message, message.getAllRecipients());
		
		transport.close();
	}
	
	
	/** packet message */
	private MimeMessage packetMessage(Session session)
								throws MessagingException {
		MimeMessage message = new MimeMessage(session);
		
		message.setSubject(subject);
		
		// use multipart ot contain information
		Multipart multipart = new MimeMultipart();
		
		// set text
		BodyPart textPart = new MimeBodyPart();
		textPart.setText(body);
		multipart.addBodyPart(textPart);
		
		
		message.setContent(multipart);
		message.setFrom(new InternetAddress(TRIGGER_ADDRESS));
		message.addRecipients(Message.RecipientType.TO, to);
		
		// save the message
		message.saveChanges();
		
		return message;
	}
	
	public void setSubject(String subject) {
		this.subject = subject;
	}
	
	public void setBody(String body) {
		this.body = body;
	}
	
	public String getSubject() {
		return subject;
	}
	
	public String getBody() {
		return body;
	}
	
	public void setFrom(String from) {
		this.from = from.toLowerCase();
	}
	
	public void setTo(String to) {
		this.to = to;
	}
	
	public void setKey(String key) {
		this.key = key;
	}
	
	public int getType() {
		return TYPE;
	}
	
	public InputStream toStream() {
		return Stream.getStream(this);
	}

}
